from multiprocessing import Process, Queue
import os, time, random
import Encoder
import HttpPost
import DataAnalyze
import Teminal
import FileUtil
import serial
import sys
import logging
import log
import RawDataSave
import TimeGet
from config_ms import *

def recive(p, q, r):
	mechine = ('A','B','C','D','E','F','G','H','I','J','K','L','M','N')
	mechine_code = [0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E]
	count = [170,170,170,170,170,170,170,170,170,170,170,170,170,170]
#	print('Process to recive:%s' %os.getpid())
	Ter_num = 0
	flag_replace = ""
	
	t = serial.Serial(MASTER_COM, BAND_RATE, timeout=COM_BLOCK_TIME)
	ts = serial.Serial(SLAVE_COM, BAND_RATE, timeout=COM_BLOCK_TIME)
	while not t.isOpen():
		t = serial.Serial(MASTER_COM, BAND_RATE, timeout=COM_BLOCK_TIME)
		ts = serial.Serial(SLAVE_COM, BAND_RATE, timeout=COM_BLOCK_TIME)
	while True:
		try:	
			Teminal.send_taken(t, Ter_num, count[Ter_num])
			
			data = []
			time.sleep(REC_WAIT_TIME)

			data = Teminal.recv(t)
			ts.reset_input_buffer()

			if len(data) == 0:
				print ("Slave Send Taken Again")
				Teminal.send_taken(ts, Ter_num, count[Ter_num])
				time.sleep(REC_WAIT_TIME)
				data = Teminal.recv(ts)
				t.reset_input_buffer()
			send_str = ""

			if len(data) > 0:
				r.put(data)
#				print("Terminal  [" + mechine[Ter_num] + "]" + TimeGet.get_time_str())
				if DataAnalyze.data_correct(data, DATA_LENGTH):					
					if DataAnalyze.is_beat(data):
						timeStr = TimeGet.get_time_str()
						send_str = "Heart beat -->" + timeStr + "   " + "[" + mechine[data[-6]-0x41] + "]\n"
						send_tuple = (send_str, False)
						p.put(Encoder.beat_to_jsonList(mechine_code[Ter_num]))
						q.put(send_tuple)
					else:
						listData, count[Ter_num] = DataAnalyze.data_analyze(data, DATA_LENGTH)
						dataJson = Encoder.list_to_json(listData,time.time())
						try:
							p.put(dataJson, block=False)
						except Exception as fe:
							log.log_file_record(fe)
							TimeStr = TimeGet.get_time_str()
							make_path = TimeStr.split(' ')[0]
							data_over = p.get()
							FileUtil.file_write(data_over,'fail_upload',make_path)
							FileUtil.file_write(dataJson,'fail_upload',make_path)
							FileUtil.file_write('\n','fail_upload',make_path)

						timeStr = TimeGet.get_time_str()
						for elem in listData:
							Temp = '%d' %elem[3]
							if elem[2] == True:
								flag_replace = "True "
							else:
								flag_replace = "False" 
							send_str = "Terminal "+mechine[elem[1]-0x41]+" "+elem[0] +" "+timeStr+" "+Temp+ " " +flag_replace +"\n"
							send_tuple = (send_str, True)
							q.put(send_tuple)
				else:
					listData, ABC= DataAnalyze.data_analyze(data, DATA_LENGTH)
					dataJson = Encoder.list_to_json(listData,time.time())
					try:
						p.put(dataJson, block=False)
					except Exception as fe:
						log.log_file_record(fe)
						TimeStr = TimeGet.get_time_str()
						make_path = TimeStr.split(' ')[0]
						FileUtil.file_write(dataJson,'fail_upload',make_path)
						FileUtil.file_write('\n','fail_upload',make_path)

					timeStr = TimeGet.get_time_str()
					if listData != None:
						for elem in listData:
							Temp = '%d' %elem[3]
							if elem[2] == True:
								flag_replace = "True "
							else:
								flag_replace = "False"
							send_str = "Terminal "+mechine[elem[1]-0x41]+" "+elem[0] +" "+timeStr+" "+Temp+" "+flag_replace+"\n"
							send_tuple = (send_str, True)
							q.put(send_tuple)
					timeStr = TimeGet.get_time_str()
					send_str = "Data Error " + timeStr + "   " + "[" + mechine[Ter_num] + "]\n"
					send_tuple = (send_str, False)
					q.put(send_tuple)
			else:
				send_str = "Terminal  [" + mechine[Ter_num] + "]  is not respond!\n"
				send_tuple = (send_str, False)
				q.put(send_tuple) 

			Ter_num += 1
			if Ter_num == TER_NUM:
				Ter_num = 0
		except Exception as fe:
			log.log_file_record(fe)
			try:
				t.close()
				ts.close()
				time.sleep(3)
				ts = serial.Serial(SLAVE_COM, BAND_RATE, timeout=COM_BLOCK_TIME)
				time.sleep(3)
				t = serial.Serial(MASTER_COM, BAND_RATE, timeout=COM_BLOCK_TIME)
			except Exception as e:
				log.log_file_record(e)
				os.system("ServerStartBack.bat")


def local_print(q):
#	print('Process to local_print:%s' %os.getpid())
	while True:
		try:
			value = q.get(True)
			print(value[0])
			if value[1] == True:
				TimeStr = TimeGet.get_time_str();
				make_path = TimeStr.split(' ')[0]
				FileUtil.file_write(value[0],'data',make_path)
		except Exception as fe:
			log.log_file_record(fe)

def send(p):
#	print('Process to send:%s' %os.getpid())
	host = OBJ_HOST
	url = OBJ_URL
	while True:
		value = p.get(True)
		try:
			result = HttpPost.httpSend(host, url, PORT, value)
			print (result)
		except Exception as fe:
			log.log_file_record(fe)	
			try:
				p.put(value, block=False)
			except Exception as re:
				log.log_file_record(re)	
				TimeStr = TimeGet.get_time_str();
				make_path = TimeStr.split(' ')[0]
				data_over = p.get()
				FileUtil.file_write(data_over,'fail_upload',make_path)
				FileUtil.file_write(value,'fail_upload',make_path)
				FileUtil.file_write('\n','fail_upload',make_path)

def file_save(r):
	while True:
		try:
			value = r.get(True)
			RawDataSave.data_write(value)
		except Exception as fe:
			log.log_file_record(fe)
def main():
	try:
		q = Queue()
		p = Queue(50)
		r = Queue()
		prev = Process(target=recive, args=(p,q,r))
		ploc = Process(target=local_print, args=(q,))
		psend= Process(target=send, args=(p,))
		psave= Process(target=file_save, args=(r,))

		prev.start()
		ploc.start()
		psend.start()
		psave.start()
#		app = Application()
#		app.root.mainloop()

	except Exception as e:
		log.log_file_record(e)
		os.system("Kill.bat")

if __name__ == '__main__':
	main()

